package com.example.usb;

import android.annotation.SuppressLint;
import android.app.Presentation;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.display.DisplayManager;
import android.hardware.usb.UsbDevice;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.Display;
import android.view.Surface;
import android.view.View;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.example.usb.adapter.FaceAllAdapter;
import com.example.usb.adapter.FaceDetectAdapter;
import com.example.usb.dao.DbConstant;
import com.example.usb.dao.util.FaceDaoUtil;
import com.example.usb.thread.AutoTakePhotoThread;
import com.example.usb.thread.FaceThread;
import com.example.usb.util.PermissionListener;
import com.example.usb.util.PermissionUtil;
import com.example.usb.util.RotateTransformation;
import com.example.usb.util.SpUtils;
import com.example.usb.util.ThreadPoolUtils;
import com.example.usb.util.ToastUtil;
import com.gyf.immersionbar.ImmersionBar;
import com.lib.uvccamera.UVCCameraHelper;
import com.lib.uvccamera.bean.FaceBean;
import com.lib.uvccamera.bean.MessageEvent;
import com.lib.uvccamera.utils.AppUtil;
import com.lib.uvccamera.utils.DebugLog;
import com.lib.uvccamera.utils.FileUtils;
import com.serenegiant.usb.CameraDialog;
import com.serenegiant.usb.USBMonitor;
import com.serenegiant.usb.widget.CameraViewInterface;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;

import static com.example.usb.util.ImageUtils.bitmap2StrByte;
import static com.lib.uvccamera.utils.Aiconstant.HAS_FACE_ERROR_MESSAGE;
import static com.lib.uvccamera.utils.Aiconstant.HAS_FACE_MESSAGE;
import static com.lib.uvccamera.utils.Aiconstant.HAS_FACE_TWO_MESSAGE;
import static com.lib.uvccamera.utils.Aiconstant.NO_FACE_MESSAGE;
import static com.lib.uvccamera.utils.Aiconstant.SCREEN_FINISH;
import static com.lib.uvccamera.utils.DebugLog.LOGHsc;

public class MainActivity extends AppCompatActivity implements CameraDialog.CameraDialogParent, CameraViewInterface.Callback, PermissionListener {
    @BindView(R.id.camera_view)
    public View mTextureView;
    @BindView(R.id.iv_iamge)
    ImageView ivImage;
    @BindView(R.id.rv_head_total)
    RecyclerView rvHeadTotal; //人脸总数
    @BindView(R.id.rv_head)
    RecyclerView rvHead;
    private UVCCameraHelper mCameraHelper;
    private CameraViewInterface mUVCCameraView;
    private boolean isRequest; //是否给USB连接权限
    private boolean isPreview;  //是否可以预览
    private FaceAllAdapter allAdapter;
    public Display[] displays; //显示屏
    private AutoTakePhotoThread takePhotoThread;
    private String screenPath; //截屏的地址
    private Bitmap screenBitmap; //投屏的图片
    private ImageView imageView; //投屏的控件
    private FaceDetectAdapter faceDetectAdapter;//检测到人脸适配器
    private View decorView;
    private LinearLayoutManager gridLayoutManager;

    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 10001:
                    if (!MainActivity.this.isDestroyed()) {

                        ToastUtil.toastShortContent("fail to connect,please check resolution params");
                    }
                    break;
                case 10002:
                    if (!MainActivity.this.isDestroyed()) {
                        ToastUtil.toastShortContent("connecting");
                    }

                    break;
            }
        }
    };


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ImmersionBar.with(this).fitsSystemWindows(true).statusBarColor(R.color.color_161519).init();
        screenPath = FileUtils.ROOT_PATH + AppUtil.getPackageName(MyApplication.getContext()) + FileUtils.HEAD_SCREEN_PATH;
        EventBus.getDefault().register(this);
        ButterKnife.bind(this);
        PermissionUtil.requestPermission(this);
        initUsbCamera();
        initView();
        upDateAllHead();

    }

    private void initView() {
        //所有头像的显示
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
//        //添加Android自带的分割线
//        rvHeadTotal.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL));
        rvHeadTotal.setLayoutManager(linearLayoutManager);
        //检测到人脸的适配器
//        gridLayoutManager = new GridLayoutManager(this, 2, GridLayoutManager.HORIZONTAL, false);
        LinearLayoutManager linearLayoutManager2 = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
        //添加Android自带的分割线
//        rvHead.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        rvHead.setLayoutManager(linearLayoutManager2);
        faceDetectAdapter = new FaceDetectAdapter(this,new ArrayList<>());
        rvHead.setAdapter(faceDetectAdapter);

    }





    /**
     * 更新所有人头
     */
    private void upDateAllHead() {
        List<String> faces = FaceDaoUtil.getInstance().getFaceString();
        List<String> headList = new ArrayList<>();
        for (int i = 0; i < faces.size(); i++) {
            String figure = faces.get(i);
            String headPath = FaceDaoUtil.getInstance().getHeadPathByFigure(figure);
            DebugLog.d(LOGHsc + " 更新人头--upDateAllHead---- " + headPath);
            if (!TextUtils.isEmpty(headPath)) {
                headList.add(headPath);
            }
        }
        if (headList.size() > 0) {
            if (allAdapter == null) {
                allAdapter = new FaceAllAdapter(this, headList);
                rvHeadTotal.setAdapter(allAdapter);
            } else {
                allAdapter.setData(headList);
            }
        }

    }

    /**
     * 更新所有人头
     */
    private void upDateAllHeadTwo() {
        List<String> faces = FaceDaoUtil.getInstance().getFaceString();
        List<String> headList = new ArrayList<>();
        for (int i = 0; i < faces.size(); i++) {
            String figure = faces.get(i);
            String headPath = FaceDaoUtil.getInstance().getHeadPathByFigure(figure);
            DebugLog.d(LOGHsc + " 更新人头--upDateAllHead---- " + headPath);
            if (!TextUtils.isEmpty(headPath)) {
                headList.add(headPath);
            }

        }
        if (headList.size() > 0) {
            if (allAdapter == null) {
                allAdapter = new FaceAllAdapter(this, headList);
                rvHeadTotal.setAdapter(allAdapter);
            } else {
                allAdapter.setData(headList);
            }
        }


    }

    /**
     * 开始截屏
     */
    private void screenPic() {
        if(decorView!=null){

            decorView.destroyDrawingCache();
        }
        if(screenBitmap!=null){
            screenBitmap.recycle();
        }
        //获取当前屏幕的大小
        int width = getWindow().getDecorView().getRootView().getWidth();
        int height = getWindow().getDecorView().getRootView().getHeight();
        //生成相同大小的图片
          screenBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        //找到当前页面的跟布局
        decorView = getWindow().getDecorView().getRootView();
        //设置缓存
        decorView.setDrawingCacheEnabled(true);
        decorView.buildDrawingCache();
        //从缓存中获取当前屏幕的图片
        screenBitmap = decorView.getDrawingCache();
        //保存图片
        if (screenBitmap != null && width > 0 && height > 0) {
            FileUtils.saveScreenPic(bitmap2StrByte(screenBitmap), screenPath);
        }

    }

    /**
     * 初始化usb设备
     */
    private void initUsbCamera() {
        mUVCCameraView = (CameraViewInterface) mTextureView;

        mCameraHelper = UVCCameraHelper.getInstance();
        //设置帧率格式
        mCameraHelper.setDefaultFrameFormat(UVCCameraHelper.FRAME_FORMAT_YUYV);
        //调整对比度
        mCameraHelper.setModelValue(UVCCameraHelper.MODE_BRIGHTNESS, 0);
        //调整亮度
        mCameraHelper.setModelValue(UVCCameraHelper.MODE_BRIGHTNESS, 0);
        //设置surfaceview的回调
        mUVCCameraView.setCallback(this);
        //监听usb链接
        mCameraHelper.initUSBMonitor(this, mUVCCameraView, listener);
        takePhotoThread = new AutoTakePhotoThread(mCameraHelper, handler);
        //操作一些自动拍照线程
//        handler.postDelayed(takePhotoThread, DbConstant.AUTO_TAKE_PIC);
    }

    /**
     * USB连接监听
     */
    private UVCCameraHelper.OnMyDevConnectListener listener = new UVCCameraHelper.OnMyDevConnectListener() {

        @Override
        public void onAttachDev(UsbDevice device) {
            // called by checking usb device
            // do request device permission
            if (mCameraHelper == null || mCameraHelper.getUsbDeviceCount() == 0) {
                if (!MainActivity.this.isDestroyed()) {
//                ToastUtil.toastShortContent("check no usb camera");
                }
                DebugLog.d(LOGHsc + " check no usb camera");
                return;
            }
            // request open permission
            if (!isRequest) {
                isRequest = true;
                if (mCameraHelper != null) {
                    mCameraHelper.requestPermission(0);
                }
            }
        }

        @Override
        public void onDettachDev(UsbDevice device) {
            // called by taking out usb device
            // do close camera
            if (isRequest) {
                isRequest = false;
                mCameraHelper.closeCamera();
                DebugLog.d(LOGHsc + device.getDeviceName() + " is out");
//                ToastUtil.toastShortContent(device.getDeviceName() + " is out");
            }
        }

        @Override
        public void onConnectDev(UsbDevice device, boolean isConnected) {
            // called by connect to usb camera
            // do open camera,start previewing
            //连接到usb设备的回调
            if (!isConnected) {
                DebugLog.d(LOGHsc + " fail to connect,please check resolution params");
                handler.sendEmptyMessage(10001);

                isPreview = false;
            } else {
                isPreview = true;
                handler.sendEmptyMessage(10002);

                DebugLog.d(LOGHsc + " connecting---");
                handler.postDelayed(takePhotoThread, DbConstant.AUTO_TAKE_PIC);
            }

        }

        @Override
        public void onDisConnectDev(UsbDevice device) {
            // called by disconnect to usb camera
            // do nothing
            //拔出usb的回调，移除线程
            DebugLog.d(LOGHsc + " disconnecting usb断开连接---");
            ToastUtil.toastShortContent("disconnecting usb断开连接 " + mCameraHelper.isCameraOpened());
            handler.removeCallbacksAndMessages(null);
        }
    };

    @Override
    public void onSurfaceCreated(CameraViewInterface view, Surface surface) {
        if (!isPreview && mCameraHelper.isCameraOpened()) {
            mCameraHelper.startPreview(mUVCCameraView);
            isPreview = true;
        }
    }

    @Override
    public void onSurfaceChanged(CameraViewInterface view, Surface surface, int width, int height) {

    }

    @Override
    public void onSurfaceDestroy(CameraViewInterface view, Surface surface) {
        if (isPreview && mCameraHelper.isCameraOpened()) {
            mCameraHelper.stopPreview();
            isPreview = false;
        }
    }

    @Override
    public void onGranted() {
        SpUtils.putBoolean(PermissionUtil.permission, true);
        FileUtils.createFileDir(FileUtils.ROOT_PATH + AppUtil.getPackageName(MyApplication.getContext()));
        //创建人头文件夹
        FileUtils.createFileDir(FileUtils.ROOT_PATH + AppUtil.getPackageName(MyApplication.getContext()) + FileUtils.HEAD_PATH);
        //创建截屏文件夹
        FileUtils.createFileDir(screenPath);
        startFigureThread();

    }

    //<editor-fold desc="人脸识别线程启动">
    private void startFigureThread() {
        DebugLog.d(LOGHsc + " startFigureThread-- ");
        ThreadPoolUtils.initThreadPoolUtils(ThreadPoolUtils.FixedThread, 50).execute(new FaceThread());

    }

    @Override
    public void onDenied(List<String> deniedPermissions) {
        SpUtils.putBoolean(PermissionUtil.permission, false);
    }

    @Override
    public USBMonitor getUSBMonitor() {
        return mCameraHelper.getUSBMonitor();
    }

    @Override
    public void onDialogResult(boolean canceled) {

    }

    @Override
    protected void onResume() {
        super.onResume();
        if (isPreview && isRequest && mCameraHelper.isCameraOpened()) {
            //设置像素宽高
//            mCameraHelper.updateResolution(720, 1280);
            mCameraHelper.updateResolution(1080, 1920);
            //设置自动对焦
            mCameraHelper.startCameraFoucs();
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        // step.2 register USB event broadcast
        if (mCameraHelper != null) {
            mCameraHelper.registerUSB();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        // step.3 unregister USB event broadcast
        if (mCameraHelper != null) {
            mCameraHelper.unregisterUSB();
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void MsgEvent(MessageEvent msgEvent) {
        List<FaceBean> beans = msgEvent.getBeans();
//        DebugLog.d(LOGHsc+" beans-----size  "+beans==null?"空":beans.size()+"");
        switch (msgEvent.getRequestCode()) {
            case NO_FACE_MESSAGE:
                FaceBean faceBean = beans.get(0);
//                rvHead.setVisibility(View.GONE);
                if (TextUtils.isEmpty(faceBean.getFirger())) {
                    //无人脸
//                    rvHead.setVisibility(View.GONE);
                    ToastUtil.toastLongContent("检测没有人脸");
                }
                loadUrl(faceBean.getImagePath(),ivImage);
                break;
            case HAS_FACE_MESSAGE:
                DebugLog.d(LOGHsc+" beans----有一个人脸  ");
//                rvHead.setVisibility(View.VISIBLE);
                FaceBean faceBean1 = beans.get(0);
//                setImage(faceBean1.getImagePath(), ivImage);
                loadUrl(faceBean1.getImagePath(),ivImage);
//                updatePicHeadTwo(beans);
                //获取本地数据的人头路径
                faceDetectAdapter.updateHead(beans);
                upDateAllHeadTwo();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        //                //开始截屏
                        screenPic();
                    }
                },1000);


                break;
            case HAS_FACE_TWO_MESSAGE:
                DebugLog.d(LOGHsc+" beans----有多个人脸  ");
                ToastUtil.toastLongContent("人脸个数... "+beans.size());
//                rvHead.setVisibility(View.VISIBLE);
                //TODO:显示UI
                FaceBean faceBean2 = beans.get(0);
//                setImage(faceBean2.getImagePath(), ivImage);
                loadUrl(faceBean2.getImagePath(),ivImage);
//                updatePicHeadTwo(beans);
                faceDetectAdapter.updateHead(beans);
                upDateAllHeadTwo();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        //                //开始截屏
                        screenPic();
                    }
                },1000);

                break;
            case HAS_FACE_ERROR_MESSAGE:
                DebugLog.d(LOGHsc+" beans----人脸解析错误  ");
//                rvHead.setVisibility(View.GONE);
                FaceBean faceBean3 = beans.get(0);
                loadUrl(faceBean3.getImagePath(),ivImage);
//                setImage(faceBean3.getImagePath(), ivImage);
                break;
            case SCREEN_FINISH:
                DebugLog.d(LOGHsc+" beans----开始投屏----   ");
                //投屏
                touping();

                break;
//            case SCREEN_OK:
//                DebugLog.d(LOGHsc+" beans----开始截屏----   ");
//                //开始截屏
//                screenPic();
//                break;

        }
    }

    /**
     * 点击投屏
     */
    private void touping() {
        this.displays = getDisplay();
        int i = this.displays.length;
        if (i > 1) {
            showDisplay();
            return;
        }
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("");
        stringBuilder.append(i);
        String count = stringBuilder.toString();
        AlertDialog.Builder localBuilder = new AlertDialog.Builder(this).setTitle("标题");
        StringBuilder localStringBuilder = new StringBuilder();
        localStringBuilder.append("当前只有 ");
        localStringBuilder.append(count);
        localStringBuilder.append(" 个屏幕，不能投屏");
        localBuilder.setMessage(localStringBuilder.toString()).setPositiveButton("确定", null).show();
    }

    private void showDisplay() {
        new DifferentDislay(this, this.displays[1]).show();
    }

    public class DifferentDislay extends Presentation {
        public DifferentDislay(Context paramContext, Display paramDisplay) {
            super(paramContext, paramDisplay);
        }

        protected void onCreate(Bundle paramBundle) {
            super.onCreate(paramBundle);
            setContentView(R.layout.aitivity_screen);
            imageView = findViewById(R.id.iv_screen);
            showScreenImage(screenBitmap);
//            setImage(screenPath,imageView);
        }
    }

    /**
     * 显示投屏图片
     *
     * @param screenBitmap
     */
    private void showScreenImage(Bitmap screenBitmap) {
        imageView.setImageBitmap(screenBitmap);
    }

    /**
     * HDMI显示类型以及支持WIFI Display 协议( MIRACAST)，实现本地设备在远程显示器上的镜像显示
     *
     * @return
     */
    @SuppressLint("WrongConstant")
    public Display[] getDisplay() {
        return ((DisplayManager) getSystemService("display")).getDisplays();
    }

    /**
     * 显示图片
     *
     * @param headPath  人脸图片
     * @param imageView 控件
     */
    public void setImage(String headPath, ImageView imageView) {
        Bitmap bm = BitmapFactory.decodeFile(headPath);
        imageView.setImageBitmap(bm);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        FileUtils.releaseFile();
        EventBus.getDefault().unregister(this);
        // step.4 release uvc camera resources
        if (mCameraHelper != null) {
            mCameraHelper.release();
        }
        if (handler != null) {
            handler.removeCallbacksAndMessages(null);
        }
        android.os.Process.killProcess(android.os.Process.myPid());
    }


    //解决横竖屏切换生命周期重走
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {

//            Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
        } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
//            Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
        }

    }

    /**
     * 解析图片
     *
     * @param url       地址
     * @param imageView 图片
     */
    private void loadUrl(String url, ImageView imageView) {
        Glide.with(this)
                .load(url)
                .asBitmap()
                .centerCrop()
                .placeholder(R.mipmap.face_defult)
                .transform(new RotateTransformation(MainActivity.this,270f))
                .error(android.R.drawable.ic_menu_report_image).listener(new RequestListener<String, Bitmap>() {
            @Override
            public boolean onException(Exception e, String model, Target<Bitmap> target, boolean isFirstResource) {
                Glide.with(MainActivity.this)
                        .load(url)
                        .asBitmap()
                        .centerCrop()
                        .placeholder(R.mipmap.face_defult)
                        .transform(new RotateTransformation(MainActivity.this,270f))
                        .into(imageView);
                return false;
            }

            @Override
            public boolean onResourceReady(Bitmap resource, String model, Target<Bitmap> target, boolean isFromMemoryCache, boolean isFirstResource) {
                return false;
            }
        }).into(imageView);
    }


    /**
     * 旋转图片
     * @param angle 被旋转角度
     * @param bitmap 图片对象
     * @return 旋转后的图片
     */
    public static Bitmap rotaingImageView(int angle, Bitmap bitmap) {

        Bitmap returnBm = null;
        // 根据旋转角度，生成旋转矩阵
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        try {
            // 将原始图片按照旋转矩阵进行旋转，并得到新的图片
            returnBm = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        } catch (OutOfMemoryError e) {
        }
        if (returnBm == null) {
            returnBm = bitmap;
        }
        if (bitmap != returnBm) {
            bitmap.recycle();
        }
        return returnBm;
    }
}
